<?php
class PluploadWidget extends CInputWidget
{
    public $uploadAction='upload';
    public $targetDir;
    public $targetPath;
    public $runtimes = 'gears,html5,flash,silverlight,browserplus';
    public $maxFileSize = '10mb';
    public $maxFileCount = 5;
    public $uniqueNames = true;
    public $resize = array('width'=>320,'height'=>240,'quality'=>90);
    public $filters = array(array('title'=>'Image files','extensions'=>'jpg,gif,png'));
    /**
    * Plupload General options
    * {@see  http://www.plupload.com/documentation.php}
    * 
    * @var array
    */
    public $options = array();
    public $baseScriptUrl;
    
    public function init()
    {
        if($this->baseScriptUrl===null)
            $this->baseScriptUrl=Yii::app()->getAssetManager()->publish(dirname(__FILE__).DIRECTORY_SEPARATOR.'assets');
    }
    
    public function run()
    {
        $this->registerClientScript();
        $this->renderUploader();
    }
    
    protected function renderUploader()
    {
        if(!isset($this->htmlOptions['id']))
            $this->htmlOptions['id']=$this->getId();

        echo CHtml::tag('div',$this->htmlOptions,'<p>You browser doesn\'t have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
');
        if (is_object($this->model))
            echo CHtml::activeHiddenField($this->model, $this->attribute);
        else
            echo CHtml::hiddenField($this->name, $this->value);
    }
    
    public function registerClientScript()
    {
        $id=$this->getId();
        $options = array(
            'runtimes'=>$this->runtimes,
            'unique_names'=>$this->uniqueNames,
            'max_file_size'=>$this->maxFileSize,
        );
        
        $options['url']=$this->getController()->createUrl($this->uploadAction);
        
        if (is_array($this->resize) && count($this->resize))
            $options['resize'] = $this->resize;
        
        if (is_array($this->filters) && count($this->filters))
            $options['filters'] = $this->filters;
        
        if (strpos($this->runtimes, 'flash') !== false)
            $options['flash_swf_url'] = $this->baseScriptUrl.'/plupload.flash.swf';
        
        if (strpos($this->runtimes, 'silverlight') !== false)
            $options['silverlight'] = $this->baseScriptUrl.'/plupload.silverlight.xap';
        
        $data = array();
        if (is_object($this->model))
        {
            $hiddenFieldId = CHtml::getActiveId($this->model,$this->attribute);
            $data = $this->model->{$this->attribute};
        }
        else
        {
            $hiddenFieldId = CHtml::getIdByName($this->name);
            $data = $this->value;
        }
        $options['init'] = array(
            'FileUploaded'=>'js:function(up, file, info) {
    info = eval("("+info.response+")");
    var data = $("#'.$hiddenFieldId.'").val();
    if (data.length > 0)
        data += ";";
    data += info.name;
    $("#'.$hiddenFieldId.'").val(data);
}'
        );
        
        //show data
        echo CHtml::openTag('div', array('class'=>'uploaded-files'));
        if (empty($data) === false)
        {
            $data = explode(';', $data);
            foreach ($data as $item)
            {
                if (preg_match('/^(.*)\.(gif|jpg|png)$/i', $item))
                {
                    $targetDir = realpath($this->targetDir);
                    $targetDir = str_replace('\\', '/', $targetDir);
                    $targerPath = str_replace(Yii::getPathOfAlias('webroot'), '', $targetDir);
                    $content = trim($targerPath,'/').'/'.$item;
                    $content = CHtml::image($content, $item, array('width'=>100,'height'=>100));
                }
                else
                    $content = $item;
                echo CHtml::tag('div', array('class'=>'file'), $content.' '.CHtml::link('Remove', '#'.$item, array('class'=>'remove')));
            }
        }
        echo CHtml::closeTag('div');
        
        if (!is_array($data)) $data = array();
        
        if ($this->maxFileCount > 0)
        {
            $options['max_file_count'] = $this->maxFileCount;
            $options['init']['FilesAdded'] = 'js:function(up, files) {
    // Check if the size of the queue is bigger than queueMaxima 
    if(up.files.length+uploaded_file_count > up.settings.max_file_count)
    {
        // Removing the extra files
        while(up.files.length+uploaded_file_count > up.settings.max_file_count)
        {
            if(up.files.length+uploaded_file_count > up.settings.max_file_count)
            {
                if (uploaded_file_count > 0)
                {
                    up.removeFile(up.files[up.files.length-1]);
                }
                else
                {
                    up.removeFile(up.files[up.settings.max_file_count]);
                }
            }
        }
        alert("Max " + up.settings.max_file_count + " files.");
    }
}';
        }
        
        $options = CMap::mergeArray($this->options, $options);
            
        if(Yii::app()->request->enableCsrfValidation)
        {
            if (!isset($options['multipart_params']))
                $options['multipart_params'] = array();
            $options['multipart_params'][Yii::app()->request->csrfTokenName] = Yii::app()->request->csrfToken;
        }
        else
            $csrf = '';
        
        
        $options=CJavaScript::encode($options);
        $cs=Yii::app()->getClientScript();
        $cs->registerCoreScript('jquery');
        //Load Queue widget CSS and jQuery
        $cs->registerCssFile($this->baseScriptUrl.'/jquery.plupload.queue/css/jquery.plupload.queue.css');
        //Third party script for BrowserPlus runtime (Google Gears included in Gears runtime now)
        if (strpos($this->runtimes, 'browserplus') !== false || strpos($this->runtimes, 'gears') !== false)
            $cs->registerScriptFile('http://bp.yahooapis.com/2.4.21/browserplus-min.js',CClientScript::POS_END);
        //Load plupload and all it's runtimes and finally the jQuery queue widget
        $cs->registerScriptFile($this->baseScriptUrl.'/plupload.full.js',CClientScript::POS_END);
        $cs->registerScriptFile($this->baseScriptUrl.'/jquery.plupload.queue/jquery.plupload.queue.js',CClientScript::POS_END);
        $cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').pluploadQueue($options);");
        $cs->registerScript(__CLASS__.'#SubmitForm'.$id,"
// Client side form validation
$('form').submit(function(e) {
    var uploader = $('#{$id}').pluploadQueue();

    // Files in queue upload them first
    if (uploader.files.length > 0) {
        // When all files are uploaded submit form
        uploader.bind('StateChanged', function() {
            if (uploader.files.length === (uploader.total.uploaded + uploader.total.failed)) {
                $('#{$id}').closest('form').get(0).submit();
            }
        });
            
        uploader.start();
        return false;
    } else {
        //alert('You must queue at least one file.');
    }
});");
        $cs->registerScript(__CLASS__.'#InitData'.$id,"
var uploaded_file_count=0;
var data_upload_fields = ".CJavaScript::encode($data).";
uploaded_file_count = data_upload_fields.length;
jQuery('.uploaded-files .remove').click(function(){
    var file = jQuery(this).attr('href').replace(/#/, '');
    var index = data_upload_fields.indexOf(file);
    data_upload_fields.splice(index, 1);
    //update limit files
    uploaded_file_count = data_upload_fields.length;
    //update data field
    jQuery('#{$hiddenFieldId}').val(data_upload_fields.join(';'));
    //remove DOM
    jQuery(this).closest('.file').remove();
    return false;
});
");
    }
}
